package dong.common;

import com.hp.webfluxclient.api.RestHandler;
import dong.bean.MethodInfo;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.Optional;

/**
 * @author dongxing
 **/
public class WebClientRestHandler implements RestHandler {

    private WebClient webClient;

    /**
     * @param serverInfo
     * @Description: 初始化webclient
     * @Author: dongxing
     * @Date: 2019-07-22 23:58
     * @return: void
     */

    @Override
    public void init(ServerInfo serverInfo) {

        this.webClient = WebClient.create(serverInfo.getUrl());
    }

    /**
     * @param serverInfo
     * @param methodInfo
     * @Description: 处理rest请求
     * @Author: dongxing
     * @Date: 2019-07-22 23:59
     * @return: void
     */

    @Override
    public Object invokeRest(ServerInfo serverInfo, MethodInfo methodInfo) {


        // 返回结果
        Object result = null;

        WebClient.RequestBodySpec accept = this.webClient
                // 请求的方法
                .method(methodInfo.getHttpMethod())
                // 请求的url和参数
                .uri(methodInfo.getUrl(), methodInfo.getParams())
                .accept(MediaType.APPLICATION_JSON);

        WebClient.ResponseSpec retrieve = null;

        // 判断是否带了body
        if (Optional.ofNullable(methodInfo.getBody()).isPresent()) {
            retrieve = accept.body(methodInfo.getBody(), methodInfo.getReturnElementType()).retrieve();

        } else {
            retrieve = accept.retrieve();
        }


        // 处理异常
        retrieve.onStatus(status -> status.value() == 404, response -> Mono.just(new RuntimeException("Not Found!")));

        //处理body
        if (methodInfo.isReturnFlux()) {
            result = retrieve.bodyToFlux(methodInfo.getReturnElementType());

        } else {
            result = retrieve.bodyToMono(methodInfo.getReturnElementType());
        }
        return result;
    }
}
